package nancal.mp.mvc.ops


import nancal.mp.db.mongo.JenkinsLanguageEnum
import nancal.mp.db.mongo.mor
import nancal.mp.service.K8sConfigMapService
import nancal.mp.service.K8sDeploymentService
import nbcp.base.annotation.Require
import nbcp.base.annotation.mvc.AdminSysOpsAction
import nbcp.base.annotation.mvc.OpenAction
import nbcp.base.comm.ApiResult
import nbcp.base.comm.JsonResult
import nbcp.base.extend.*
import nbcp.base.json.*
import nbcp.myoql.db.mongo.query
import nbcp.myoql.db.mongo.queryById
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.*
import java.time.LocalDateTime
import javax.servlet.http.HttpServletResponse

@RequestMapping("/ops/k8s/configmap")
@RestController
@AdminSysOpsAction
class K8sConfigMapController {
    companion object {
        private val logger = LoggerFactory.getLogger(this::class.java.declaringClass)
    }

    class ConfigMapSimpleData(var name: String = "", items: Set<String> = setOf())

    @Autowired
    lateinit var k8sService: K8sDeploymentService

    @Autowired
    lateinit var k8sConfigMapService: K8sConfigMapService

    /**
     * 获取某一个configmap
     */
    @RequestMapping("/get", method = arrayOf(RequestMethod.POST, RequestMethod.GET))
    fun get(
        targetEnv: String,
        namespace: String,
        @Require name: String
    ): ApiResult<Map<String, String>> {
        return k8sConfigMapService.get(targetEnv, namespace, name)
    }

    @RequestMapping("/set", method = arrayOf(RequestMethod.POST))
    fun set(
        targetEnv: String,
        namespace: String,
        @Require name: String,
        content: Map<String, String>
    ) {
        content.keys.forEach { key ->
            k8sConfigMapService.setContent(targetEnv, namespace, name, key, content.get(key)!!)
        }
        return
    }

    @Autowired
    lateinit var k8sDeployment: K8sDeploymentService;

    /***
     * 仅仅设置当前 namespace 的前后端。
     */
    @RequestMapping("/set-vue/{jenkinsLogId}", method = arrayOf(RequestMethod.POST, RequestMethod.GET))
    fun setNginxConfigmap(
        @PathVariable jenkinsLogId: String,
        response: HttpServletResponse
    ): JsonResult {

        var log = mor.dev.jenkinsLog.queryById(jenkinsLogId).toEntity()
            .must()
            .elseThrow { "找不到发版信息" }

        var targetEnv = log.buildInfo.targetEnv
        var namespace = log.buildInfo.clusterCode
        var location = log.buildInfo.appName
        var serviceName = log.buildInfo.serviceName


        if (location.isNullOrEmpty()) {
            throw RuntimeException("虚拟目录不能为空，请检查项目设置")
        }

        if (k8sConfigMapService.setNginxConfWebConf(targetEnv, namespace, location, serviceName)) {
            k8sDeployment.restart(targetEnv, namespace, "nginx");
        }

        response.status = 200;
        return JsonResult();
    }


    @PostMapping("/set-nginx-configmap/{namespace}")
    fun setNginxConfigmap(@Require namespace: String): JsonResult {

        var listResult = k8sService.list("", namespace, language = JenkinsLanguageEnum.Vue)

        if (listResult.hasError) {
            return JsonResult.error(listResult.msg);
        }

        var defList = mor.dev.gitData.query()
            .where { it.language mongoEquals JenkinsLanguageEnum.Vue }
            .toList();

        var appList = defList.map { def -> def.folders }.Unwind();

        var getProductLineCode = ss@{ name: String ->
            return@ss defList.firstOrNull { folder -> folder.folders.map { it.name }.contains(name) }?.productLine?.code
        }


        var needRestartNginx = false;
        listResult.data.forEach { vue ->
            var def = appList.firstOrNull {
                it.name == vue.name ||
                        (getProductLineCode(it.name) + "-" + it.name) == vue.name ||
                        (getProductLineCode(it.name) + "-" + it.name + "-vue") == vue.name ||
                        (it.name + "-vue") == vue.name
            }
            if (def == null) {
                return@forEach
            }

            needRestartNginx =
                needRestartNginx || k8sConfigMapService.setNginxConfWebConf(
                    "",
                    namespace,
                    def.location.AsString(def.name),
                    vue.name
                )
        }


        if (needRestartNginx) {
            //重启nginx，与部署的重启机制不同。
            k8sDeployment.setEnv("", namespace, "nginx", 0, LocalDateTime.now().AsString())
        }

        return JsonResult();
    }

//    @RequestMapping("/restart-nginx", method = arrayOf(RequestMethod.POST, RequestMethod.GET))
//    fun restartNginx(targetEnv: String, namespace: String) {
//        var k8s_ns = namespace.AsString(config.appGroup)
//        k8sService.restart(targetEnv, k8s_ns, "nginx")
//    }

//    fun String.removeHead1Line(): String {
//        return this.split("\n").Slice(1).joinToString("\n")
//    }
//
//    data class VPathData(var jobName: String = "", var vpath: String = "", var port: Int = 0) {
//        fun getInfo(): String {
//            return this.jobName + ":" + this.port + (if (vpath.startsWith("/")) vpath else "/" + vpath);
//        }
//    }

}